<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>

    // class 继承 
    // Class 可以通过extends关键字实现继承，让子类继承父类的属性和方法。
    // extends 的写法比 ES5 的原型链继承，要清晰和方便很多。 => ES6 extends 默认就自带原型继承(压根不需要咱们写)

    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        skill() {
            console.log("thinging studying");
        }
        say() {
            console.log(this.name, this.age);
        }

    }
    Person.prototype.species = "human";


    // 1. 不仅要继承父类的(实例化对象相关属性和方法  原型对象相关属性和方法),还要定义自己的(实例化对象相关属性和方法  原型对象相关属性和方法)
    // a. 继承父类实例化对象相关属性和方法 
    // b. 继承父类原型对象相关属性和方法  (ES6 class继承自带原型继承)

    class YellowPerson extends Person{
        // 构造函数继承
        constructor(name,age,hobby){
            // 报错: 在访问“this”或从派生构造函数返回之前，必须调用派生类中的super构造函数
            // Person.call(this,name,age); /// ES5 调用父类构造函数 => ES6 不适用

            // 注意: 要先继承父类的 在定义自己的(可选)
            super(name,age); // 调用父类构造函数  等价于  Person.call(this,name,age);
            this.hobby = hobby;
        }

        // ES6 class继承自带原型继承 => 默认已经继承父类原型对象相关属性和方法  所以不需要手动配置 => 只需要定义自己的

        speak(){
            console.log("chinese");
        }

    }

    var yp = new YellowPerson("张三",18,"唱歌");
    console.log(yp);



    // 2. 不仅要继承父类的(实例化对象相关属性和方法  原型对象相关属性和方法),还要定义自己的(原型对象相关属性和方法)

    //  注意: 如果只继承父类实例化对象相关属性和方法, 不定义自己实例相关的属性和方法   constructor 可以省略
    /* class YellowPerson extends Person{
        // 构造函数继承
        // constructor(name,age){
        //     // 只继承父类的不定义自己实例相关的属性和方法
        //     super(name,age); // 调用父类构造函数  等价于  Person.call(this,name,age);
        // }

        // ES6 class继承自带原型继承 => 默认已经继承父类原型对象相关属性和方法  所以不需要手动配置 => 只需要定义自己的

        speak(){
            console.log("chinese");
        }

    }

    var yp = new YellowPerson("张三",18,"唱歌");
    console.log(yp); */


    // 3. 全部都继承父类的(实例化对象相关属性和方法  原型对象相关属性和方法),但是不定义自己的(实例化对象相关属性和方法  原型对象相关属性和方法)

   /*  class YellowPerson extends Person{
        
    };
    var yp = new YellowPerson("张三",18,"唱歌");
    console.log(yp); */



</script>

</html>